package com.ruoyi.brand;

import cn.hutool.core.util.IdUtil;
import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.io.image.ImageData;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.*;
import com.itextpdf.layout.properties.*;
import com.ruoyi.base.domain.vo.LotteryVo;
import com.ruoyi.config.PDFConstants;
import com.ruoyi.utils.LotteryUtil;
import com.ruoyi.utils.PropertiesDailyGenerator;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;

@Slf4j
@Component
public class ShanDong3DFushi {

    //private static String uploadPath = "D:\\service\\upload\\";
    private static String uploadPath = PDFConstants.uploadPath;
    private static SimpleDateFormat sdfymd = new SimpleDateFormat("yyyyMMdd");

    // 缓存字体数据，避免重复加载
    private static Map<String, byte[]> fontCache = new HashMap<>();
    private static Map<String, byte[]> imageCache = new HashMap<>();

    public static Map<String,String> generateLotteryTicket(LotteryVo lotteryVo) {
        Map<String,String> map = new HashMap<>();
        map.put("money","");
        map.put("path","");
        map.put("status","yes");
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
            SimpleDateFormat sdfYear = new SimpleDateFormat("yy-MM-dd");
            SimpleDateFormat years = new SimpleDateFormat("yyyy");

            String outPath = uploadPath + File.separator + sdfymd.format(new Date()) + File.separator;
            File folder = new File(outPath);

            // 文件夹不存在，创建文件夹（包括父目录）
            if (!folder.exists()) {
                folder.mkdirs();
            }

            String fileOutPath = outPath + IdUtil.getSnowflakeNextId() + ".pdf";
            File outFile = new File(fileOutPath);
            if (!outFile.exists()) {
                System.out.println(outFile.getPath());
                outFile.createNewFile();
            }

            PageSize pageSize = new PageSize(mmToPoints(80), mmToPoints(101));

            // 创建PDF文档
            PdfWriter writer = new PdfWriter(fileOutPath);
            PdfDocument pdf = new PdfDocument(writer);
            Document document = new Document(pdf, pageSize); // 使用小尺寸页面

            float topMargin = mmToPoints(8);    // 上下边距
            float bottmoMargin = mmToPoints(3);
            float leftRightMargin = mmToPoints(5); // 左右边距
            document.setMargins(topMargin, leftRightMargin, bottmoMargin, leftRightMargin);

            // 设置中文字体（需要确保系统有中文字体）
            PdfFont font = PdfFontFactory.createFont();
            document.setFont(font);

            // 修改字体加载方式 - 使用 ClassPathResource
            byte[] hb1FontData = loadFontData("fonts/hb1.otf");
            byte[] stFontData = loadFontData("fonts/宋体与数字结合.ttf");

            if (hb1FontData == null || stFontData == null) {
                log.error("字体文件加载失败");
                return null;
            }

            int mone = (lotteryVo.getNumbers() * lotteryVo.getMultiple().intValue()) * 2;
            String qishu = years.format(new Date()) + PropertiesDailyGenerator.getDailyStage();

            String cpType = lotteryVo.getRemark();
            String hjzhu = String.valueOf(lotteryVo.getNumbers());
            String bs = String.valueOf(lotteryVo.getMultiple());
            String zhum = lotteryVo.getLotteryNo();
            String money = String.valueOf(mone);
            String code = LotteryUtil.generateStrNum();
            log.info("生成的随机码：" + code);
            String kjq = qishu + " " + sdfYear.format(new Date());
            String xsq = qishu + "-" + PropertiesDailyGenerator.getDailySort();
            String xssj = sdf.format(new Date());
            String address = "地址：山东省枣庄市市中区好运有你福彩专营店";

            double result = mone * 0.34;
            String formattedResult = String.format("%.2f", result);
            String gongyi = "感谢您为公益事业贡献" + formattedResult + "元";

            // 修改字体创建方式 - 使用字节数组
            PdfFont customFont = PdfFontFactory.createFont(hb1FontData, PdfEncodings.IDENTITY_H);
            PdfFont customFontst = PdfFontFactory.createFont(stFontData, PdfEncodings.IDENTITY_H);
            PdfFont bdfh = PdfFontFactory.createFont(hb1FontData, PdfEncodings.IDENTITY_H);

            Text textbd = new Text(": ");
            textbd.setFontSize(12f);
            textbd.setFont(bdfh);
            textbd.setBold();

            // 添加标题
            Paragraph title = new Paragraph("玩法:3D-复式                机号:37040015")
                    .setFont(customFont)
                    .setFontSize(9.5F)
                    .setTextAlignment(TextAlignment.LEFT);
            document.add(title);

            // 添加代码信息
            Paragraph pcode = new Paragraph(code)
                    .setMarginTop(-7)
                    .setFont(customFont)
                    .setFontSize(9.5F)
                    .setTextAlignment(TextAlignment.LEFT);
            document.add(pcode);

            Div div = new Div();
            // 设置固定高度
            div.setHeight(UnitValue.createPointValue(mmToPoints(36)));
            div.setTextAlignment(TextAlignment.CENTER);
            div.setProperty(Property.JUSTIFY_CONTENT, JustifyContent.CENTER); // 垂直居中

            Text rightTextElement = new Text(hjzhu);
            rightTextElement.setFontSize(12f);
            rightTextElement.setBold();

            Text rightTextElement2 = new Text("注");
            rightTextElement2.setFontSize(10.5f);

            // 添加组三复式投注信息
            Paragraph betType = new Paragraph(cpType)
                    .setMarginTop(20)
                    .setFont(customFont)
                    .setFontSize(10.5f)
                    .setTextAlignment(TextAlignment.CENTER)
                    .add(textbd)
                    .add("\t")
                    .add("合计")
                    .addTabStops(new TabStop(250f, TabAlignment.RIGHT))
                    .add("\t")
                    .add(rightTextElement)
                    .add("\t")
                    .add(rightTextElement2);
            div.add(betType);

            Text textzm = new Text(zhum);
            textzm.setFontSize(12f);
            textzm.setFont(customFontst);
            textzm.setBold();
            // 添加注释和倍数
            Paragraph comment = new Paragraph("注码")
                    .setMarginTop(-5)
                    .setFont(customFont)
                    .setFontSize(10.5f)
                    .setTextAlignment(TextAlignment.LEFT)
                    .setMarginLeft(65)
                    .add(textbd)
                    .add(textzm);
            div.add(comment);

            Text textbs = new Text(bs);
            textbs.setFontSize(12f);
            textbs.setFont(customFontst);
            textbs.setBold();
            Paragraph multiple = new Paragraph("倍数")
                    .setMarginTop(-5)
                    .setFont(customFont)
                    .setFontSize(10.5f)
                    .setTextAlignment(TextAlignment.LEFT)
                    .setMarginLeft(65)
                    .add(textbd)
                    .add(textbs);
            div.add(multiple);
            document.add(div);

            Text texthj = new Text(money);
            texthj.setFontSize(12f);
            texthj.setFont(customFontst);
            texthj.setBold();

            Text textbd2 = new Text(":");
            textbd2.setFontSize(12f);
            textbd2.setFont(bdfh);
            textbd2.setBold();

            Paragraph kaijiang = new Paragraph("开奖期：" + kjq + "    合计")
                    .setMarginTop(-5)
                    .setFont(customFont)
                    .setFontSize(9)
                    .setTextAlignment(TextAlignment.LEFT)
                    .add(textbd2)
                    .add(texthj)
                    .add("元");
            document.add(kaijiang);

            Paragraph xiaoshou = new Paragraph("销售期：" + xsq + "     " + xssj)
                    .setMarginTop(-5)
                    .setFont(customFont)
                    .setFontSize(9)
                    .setTextAlignment(TextAlignment.LEFT);
            document.add(xiaoshou);

            // 添加地址信息
            Paragraph paddress = new Paragraph(address)
                    .setMarginTop(-5)
                    .setFont(customFont)
                    .setFontSize(9)
                    .setTextAlignment(TextAlignment.LEFT);
            document.add(paddress);

            // 添加公益信息
            Paragraph donation = new Paragraph(gongyi)
                    .setMarginTop(-5)
                    .setFont(customFont)
                    .setFontSize(9)
                    .setTextAlignment(TextAlignment.LEFT);
            document.add(donation);

            // 修改图片加载方式 - 使用 ClassPathResource
            byte[] imageDataBytes = loadImageData("static/1.png");
            if (imageDataBytes != null) {
                ImageData imageData = ImageDataFactory.create(imageDataBytes);
                Image image = new Image(imageData);

                // 设置图片大小
                image.setWidth(mmToPoints(91));  // 91mm宽度
                image.setHeight(mmToPoints(25)); // 22.5mm高度
                image.setMarginTop(-5);
                image.setMarginLeft(-3);
                image.setBold();
                image.setAutoScale(true);

                // 创建段落并添加图片
                Paragraph pimage = new Paragraph();
                pimage.add(image);
                document.add(pimage);
            } else {
                log.warn("图片文件加载失败: static/1.png");
            }

            document.close();

            map.put("money",money);
            map.put("path",fileOutPath);
            return map;
        } catch (Exception e) {
            e.printStackTrace();
            map.put("status","no");
            return map;
        }
    }

    /**
     * 从 classpath 加载字体数据
     */
    private static byte[] loadFontData(String fontPath) {
        return fontCache.computeIfAbsent(fontPath, path -> {
            try {
                ClassPathResource resource = new ClassPathResource(path);
                if (!resource.exists()) {
                    log.error("字体文件不存在: {}", path);
                    return null;
                }
                try (java.io.InputStream inputStream = resource.getInputStream()) {
                    byte[] fontData = org.apache.commons.io.IOUtils.toByteArray(inputStream);
                    log.info("成功加载字体文件: {}, 大小: {} bytes", path, fontData.length);
                    return fontData;
                }
            } catch (Exception e) {
                log.error("加载字体文件失败: {}", path, e);
                return null;
            }
        });
    }

    /**
     * 从 classpath 加载图片数据
     */
    private static byte[] loadImageData(String imagePath) {
        return imageCache.computeIfAbsent(imagePath, path -> {
            try {
                ClassPathResource resource = new ClassPathResource(path);
                if (!resource.exists()) {
                    log.error("图片文件不存在: {}", path);
                    return null;
                }
                try (java.io.InputStream inputStream = resource.getInputStream()) {
                    byte[] imageData = org.apache.commons.io.IOUtils.toByteArray(inputStream);
                    log.info("成功加载图片文件: {}, 大小: {} bytes", path, imageData.length);
                    return imageData;
                }
            } catch (Exception e) {
                log.error("加载图片文件失败: {}", path, e);
                return null;
            }
        });
    }

    private Cell createCell(String text, int fontSize, boolean bold) {
        Paragraph paragraph = new Paragraph(text)
                .setFontSize(fontSize);
        if (bold) {
            paragraph.setBold();
        }
        return new Cell().add(paragraph).setPadding(2);
    }

    /**
     * 毫米转点
     */
    private static float mmToPoints(float mm) {
        return mm * 2.83465f;
    }

    /**
     * 像素转换为点
     */
    private float pixelsToPoints(float pixels) {
        return pixels * 0.75f;
    }

    /**
     * 转换PDF为BMP图片列表
     */
    private static List<String> convertPdfToBmpFiles(byte[] pdfBytes, String outputBaseName) {
        List bmpFiles = new ArrayList<>();
        try {
            String outPath = uploadPath + sdfymd.format(new Date()) + File.separator;
            File folder = new File(outPath);

            // 文件夹不存在，创建文件夹（包括父目录）
            if (!folder.exists()) {
                folder.mkdirs();
            }
            ByteArrayInputStream bis = new ByteArrayInputStream(pdfBytes);
            PDDocument document = PDDocument.load(bis);
            String fileName = outPath + outputBaseName + ".pdf";
            File outFile = new File(fileName);
            if (!outFile.exists()) {
                System.out.println(outFile.getPath());
                outFile.createNewFile();
            }

        } catch (IOException e) {
            throw new RuntimeException("PDF转换BMP失败", e);
        }
        return bmpFiles;
    }

    public static void main(String[] args) {
        //generateLotteryTicket();
    }
}